#pragma once

#include "iostream"
#include "vector"
#include "algorithm"
#include "semaphore.h"
#include "pthread.h"

using namespace std;
/*HJJ QQ479287006
 *你一个类：

class FooBar {
  public void foo() {
    for (int i = 0; i < n; i++) {
      print("foo");
    }
  }

  public void bar() {
    for (int i = 0; i < n; i++) {
      print("bar");
    }
  }
}
两个不同的线程将会共用一个 FooBar 实例：

线程 A 将会调用 foo() 方法，而
线程 B 将会调用 bar() 方法
请设计修改程序，以确保 "foobar" 被输出 n 次。

 

示例 1：

输入：n = 1
输出："foobar"
解释：这里有两个线程被异步启动。其中一个调用 foo() 方法, 另一个调用 bar() 方法，"foobar" 将被输出一次。

来源：力扣（LeetCode）
链接：https://leetcode.cn/problems/print-foobar-alternately
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * */

//int n1;
//sem_t p1,p2;
//void FooBar(int n) {
//    sem_init(&p1,0,1);
//    sem_init(&p2,0,0);
//    n1=n;
//}
//
//void foo(function<void()> printFoo) {
//
//    for (int i = 0; i < n; i++) {
//
//        sem_wait(&p1);
//        printFoo();
//        sem_post(&p2);
//    }
//}
//
//void bar(function<void()> printBar) {
//
//    for (int i = 0; i < n; i++) {
//        sem_wait(&p2);
//        printBar();
//        sem_post(&p1);
//
//    }
//}



int n1;
pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;

void FooBar(int n) {

    n1 = n;
    pthread_mutex_lock(&lock2);
}

void foo(function<void()> printFoo) {

    for (int i = 0; i < n; i++) {
        pthread_mutex_lock(&lock1);
        printFoo();
        pthread_mutex_unlock(&lock2);
    }
}

void bar(function<void()> printBar) {

    for (int i = 0; i < n; i++) {

        pthread_mutex_lock(&lock2);
        printBar();
        pthread_mutex_unlock(&lock1);

    }
}